// -----------------------------
// Author: 		Dhaenens Gert	
// Creation: 	2/22/2015 12:39:01 PM				
// -----------------------------

#include "ShaderLoader.h"

#include "Engine.h"
#include "GraphicsManager.h"
#include "JobManager.h"

#include "FileManager.h"
#include "FilePackage.h"
#include "File.h"

#include "IVertexShader.h"
#include "IPixelShader.h"
#include "IMutex.h"
#include "IPlatform.h"

#include "PlatformProvider.h"

#include "Path.h"

#define X32TOX8(x)		((Byte) (x * 255.0f))

namespace Flow
{

	IMutex* ShaderLoader::s_LibPNGLock = nullptr;

	ShaderLoader::ShaderLoader(IGraphicsDevice* lpDevice, IMutex* lpGraphicsMutex, const tstring& file, ShaderType::Enum shaderType)
		: m_lpGraphicsDevice(lpDevice)
		, m_lpGraphicsMutex(lpGraphicsMutex)
		, m_lpShader(nullptr)
		, m_FilePath(file)
		, m_ShaderType(shaderType)
		, m_lpFile(nullptr)
	{
	}

	ShaderLoader::~ShaderLoader()
	{
	}

	IShader* ShaderLoader::Load()
	{
		string str = string(m_FilePath.begin(), m_FilePath.end());
		Log::WriteLine("Loading Texture \"%s\".", str.c_str());

		if (m_ShaderType == ShaderType::Vertex)
			m_lpShader = PlatformProvider::QueryInterface<IVertexShader>("VertexShader");
		else if (m_ShaderType == ShaderType::Pixel)
			m_lpShader = PlatformProvider::QueryInterface<IPixelShader>("PixelShader");
		else
			ASSERT(false && "Invalid Shader Target");
		ASSERT(m_lpShader);

		Engine::Jobs->QueueJob(this);

		return m_lpShader;
	}
	void ShaderLoader::Run()
	{
		string str = string(m_FilePath.begin(), m_FilePath.end());
		Log::WriteLine("Reading Shader Data from file \"%s\".", str.c_str());

		// Find the Package
		FilePackage* lpPackage = Engine::Files->FindPackageForFile(m_FilePath);
		ASSERT(lpPackage);
		if (!lpPackage)
		{
			Log::WriteLine("Could not find package for file \"%s\".", str.c_str());
			return;
		}
		tstring packageName = lpPackage->GetName();
		string pstr = string(packageName.begin(), packageName.end());
		Log::WriteLine("Found package \"%s\" for file \"%s\".", pstr.c_str(), str.c_str());

		// Get the File
		m_lpFile = lpPackage->GetFile(m_FilePath);
		ASSERT(m_lpFile);

		// Read the File Data
		void* lpData = m_lpFile->ReadAllData();
		Size_T dataSize = (Size_T) m_lpFile->GetDataSize();

		m_lpGraphicsMutex->Lock();
		//m_lpShader->Create(m_lpGraphicsDevice, lpData, dataSize);
		m_lpGraphicsMutex->Unlock();

		// Free the Shader Data
		free(lpData);

		Log::WriteLine("Finished loading Shader \"%s\".", str.c_str());
	}

}